//! # 认证提供者接口
//!
//! 统一的认证授权接口定义，支持插拔式认证方式。

use async_trait::async_trait;
use serde::{Deserialize, Serialize};

use crate::core::{AuthContext, Principal, Resource, AuthResult};

/// 认证提供者类型
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AuthProviderType {
    /// JSON Web Token 认证
    Jwt,
    /// OAuth2 认证
    OAuth2,
    /// API Key 认证
    ApiKey,
    /// Basic 认证
    Basic,
    /// LDAP 认证
    Ldap,
    /// 多因素认证
    Mfa,
    /// 自定义认证
    Custom(String),
}

impl AuthProviderType {
    /// 获取提供者类型名称
    pub fn name(&self) -> &str {
        match self {
            AuthProviderType::Jwt => "jwt",
            AuthProviderType::OAuth2 => "oauth2",
            AuthProviderType::ApiKey => "api_key",
            AuthProviderType::Basic => "basic",
            AuthProviderType::Ldap => "ldap",
            AuthProviderType::Mfa => "mfa",
            AuthProviderType::Custom(name) => name,
        }
    }

    /// 从字符串创建提供者类型
    pub fn from_str(s: &str) -> Self {
        match s.to_lowercase().as_str() {
            "jwt" => AuthProviderType::Jwt,
            "oauth2" => AuthProviderType::OAuth2,
            "api_key" | "apikey" => AuthProviderType::ApiKey,
            "basic" => AuthProviderType::Basic,
            "ldap" => AuthProviderType::Ldap,
            "mfa" => AuthProviderType::Mfa,
            _ => AuthProviderType::Custom(s.to_string()),
        }
    }
}

/// 认证提供者核心接口
/// 
/// 所有认证方式都必须实现此接口
#[async_trait]
pub trait AuthProvider: Send + Sync {
    /// 认证用户身份
    ///
    /// 根据认证上下文验证用户身份，返回主体信息。
    ///
    /// # 参数
    /// * `context` - 认证上下文，包含请求信息
    ///
    /// # 返回值
    /// * `Ok(Principal)` - 认证成功，返回主体信息
    /// * `Err(AuthError)` - 认证失败
    async fn authenticate(&self, context: &AuthContext) -> AuthResult<Principal>;

    /// 验证令牌有效性
    ///
    /// 验证给定令牌是否有效，不返回用户信息。
    ///
    /// # 参数
    /// * `token` - 要验证的令牌
    ///
    /// # 返回值
    /// * `Ok(true)` - 令牌有效
    /// * `Ok(false)` - 令牌无效
    /// * `Err(AuthError)` - 验证过程中出现错误
    async fn validate_token(&self, token: &str) -> AuthResult<bool>;

    /// 获取提供者类型
    fn provider_type(&self) -> AuthProviderType;

    /// 获取提供者名称
    fn provider_name(&self) -> &str;

    /// 获取提供者描述
    fn provider_description(&self) -> &str {
        "Generic authentication provider"
    }

    /// 检查是否支持令牌刷新
    fn supports_token_refresh(&self) -> bool {
        false
    }

    /// 刷新令牌（可选实现）
    async fn refresh_token(&self, _refresh_token: &str) -> AuthResult<String> {
        Err(crate::core::AuthError::UnsupportedOperation(
            "Token refresh not supported".to_string()
        ))
    }

    /// 注销（可选实现）
    async fn logout(&self, _principal: &Principal) -> AuthResult<()> {
        Ok(())
    }

    /// 获取用户信息（可选实现）
    async fn get_user_info(&self, _principal: &Principal) -> AuthResult<serde_json::Value> {
        Ok(serde_json::json!({}))
    }
}

/// 授权检查接口
/// 
/// 用于检查用户权限和访问控制
#[async_trait]
pub trait AuthorizationProvider: Send + Sync {
    /// 检查用户是否有权限访问资源
    ///
    /// # 参数
    /// * `principal` - 已认证的主体
    /// * `resource` - 要访问的资源
    ///
    /// # 返回值
    /// * `Ok(true)` - 授权成功
    /// * `Ok(false)` - 授权失败
    /// * `Err(AuthError)` - 检查过程中出现错误
    async fn authorize(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool>;

    /// 检查特定权限
    ///
    /// # 参数
    /// * `principal` - 已认证的主体
    /// * `permission` - 要检查的权限
    ///
    /// # 返回值
    /// * `Ok(true)` - 拥有权限
    /// * `Ok(false)` - 没有权限
    /// * `Err(AuthError)` - 检查过程中出现错误
    async fn check_permission(&self, principal: &Principal, permission: &str) -> AuthResult<bool>;

    /// 获取用户所有权限
    async fn get_user_permissions(&self, principal: &Principal) -> AuthResult<Vec<String>>;

    /// 获取用户所有角色
    async fn get_user_roles(&self, principal: &Principal) -> AuthResult<Vec<String>>;
}

/// 认证服务统一接口
/// 
/// 组合认证和授权功能的高级接口
#[async_trait]
pub trait AuthenticationService: Send + Sync {
    /// 执行完整的认证流程
    async fn authenticate(&self, context: &AuthContext) -> AuthResult<Principal>;
    
    /// 执行授权检查
    async fn authorize(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool>;
    
    /// 刷新令牌
    async fn refresh_token(&self, refresh_token: &str) -> AuthResult<String>;
    
    /// 注销用户
    async fn logout(&self, principal: &Principal) -> AuthResult<()>;
    
    /// 验证会话
    async fn validate_session(&self, session_id: &str) -> AuthResult<Principal>;
}

/// 令牌服务接口
/// 
/// 专门处理令牌生成、验证和管理
#[async_trait]
pub trait TokenService: Send + Sync {
    /// 生成访问令牌
    async fn generate_access_token(&self, principal: &Principal) -> AuthResult<String>;
    
    /// 生成刷新令牌
    async fn generate_refresh_token(&self, principal: &Principal) -> AuthResult<String>;
    
    /// 验证令牌并返回主体信息
    async fn validate_token(&self, token: &str) -> AuthResult<Principal>;
    
    /// 撤销令牌
    async fn revoke_token(&self, token: &str) -> AuthResult<()>;
    
    /// 检查令牌是否被撤销
    async fn is_token_revoked(&self, token: &str) -> AuthResult<bool>;
    
    /// 获取令牌剩余有效时间（秒）
    async fn get_token_ttl(&self, token: &str) -> AuthResult<u64>;
}

/// 权限检查器接口
/// 
/// 简化的权限检查接口
#[async_trait]
pub trait PermissionChecker: Send + Sync {
    /// 检查权限
    async fn check(&self, principal: &Principal, permission: &str) -> AuthResult<bool>;
    
    /// 检查资源访问权限
    async fn check_resource(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool>;
    
    /// 批量检查权限
    async fn check_multiple(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<Vec<bool>>;
    
    /// 检查是否拥有任一权限
    async fn check_any(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<bool>;
    
    /// 检查是否拥有所有权限
    async fn check_all(&self, principal: &Principal, permissions: &[&str]) -> AuthResult<bool>;
}

/// 会话管理器接口
/// 
/// 管理用户会话生命周期
#[async_trait]
pub trait SessionManager: Send + Sync {
    /// 创建新会话
    async fn create_session(&self, principal: &Principal) -> AuthResult<String>;
    
    /// 获取会话信息
    async fn get_session(&self, session_id: &str) -> AuthResult<Principal>;
    
    /// 更新会话
    async fn update_session(&self, session_id: &str, principal: &Principal) -> AuthResult<()>;
    
    /// 删除会话
    async fn delete_session(&self, session_id: &str) -> AuthResult<()>;
    
    /// 删除用户所有会话
    async fn delete_user_sessions(&self, user_id: &str) -> AuthResult<()>;
    
    /// 检查会话是否有效
    async fn is_session_valid(&self, session_id: &str) -> AuthResult<bool>;
    
    /// 延长会话有效期
    async fn extend_session(&self, session_id: &str, extend_by: std::time::Duration) -> AuthResult<()>;
}

/// 用户管理器接口
/// 
/// 管理用户生命周期和基本信息
#[async_trait]
pub trait UserManager: Send + Sync {
    /// 创建用户
    async fn create_user(&self, user_info: &serde_json::Value) -> AuthResult<Principal>;
    
    /// 获取用户信息
    async fn get_user(&self, user_id: &str) -> AuthResult<Principal>;
    
    /// 更新用户信息
    async fn update_user(&self, user_id: &str, user_info: &serde_json::Value) -> AuthResult<()>;
    
    /// 删除用户
    async fn delete_user(&self, user_id: &str) -> AuthResult<()>;
    
    /// 锁定用户
    async fn lock_user(&self, user_id: &str, reason: &str) -> AuthResult<()>;
    
    /// 解锁用户
    async fn unlock_user(&self, user_id: &str) -> AuthResult<()>;
    
    /// 禁用用户
    async fn disable_user(&self, user_id: &str) -> AuthResult<()>;
    
    /// 启用用户
    async fn enable_user(&self, user_id: &str) -> AuthResult<()>;
    
    /// 重置密码
    async fn reset_password(&self, user_id: &str, new_password: &str) -> AuthResult<()>;
    
    /// 验证密码
    async fn verify_password(&self, user_id: &str, password: &str) -> AuthResult<bool>;
}

/// 角色管理器接口
/// 
/// 管理角色和权限映射
#[async_trait]
pub trait RoleManager: Send + Sync {
    /// 创建角色
    async fn create_role(&self, role_name: &str, permissions: &[&str]) -> AuthResult<()>;
    
    /// 删除角色
    async fn delete_role(&self, role_name: &str) -> AuthResult<()>;
    
    /// 为角色添加权限
    async fn add_permission_to_role(&self, role_name: &str, permission: &str) -> AuthResult<()>;
    
    /// 从角色移除权限
    async fn remove_permission_from_role(&self, role_name: &str, permission: &str) -> AuthResult<()>;
    
    /// 为用户分配角色
    async fn assign_role_to_user(&self, user_id: &str, role_name: &str) -> AuthResult<()>;
    
    /// 从用户移除角色
    async fn remove_role_from_user(&self, user_id: &str, role_name: &str) -> AuthResult<()>;
    
    /// 获取角色的所有权限
    async fn get_role_permissions(&self, role_name: &str) -> AuthResult<Vec<String>>;
    
    /// 获取用户的所有角色
    async fn get_user_roles(&self, user_id: &str) -> AuthResult<Vec<String>>;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_auth_provider_type() {
        assert_eq!(AuthProviderType::Jwt.name(), "jwt");
        assert_eq!(AuthProviderType::OAuth2.name(), "oauth2");
        assert_eq!(AuthProviderType::ApiKey.name(), "api_key");
        assert_eq!(AuthProviderType::Custom("custom".to_string()).name(), "custom");
    }

    #[test]
    fn test_auth_provider_type_from_str() {
        assert_eq!(AuthProviderType::from_str("jwt"), AuthProviderType::Jwt);
        assert_eq!(AuthProviderType::from_str("OAuth2"), AuthProviderType::OAuth2);
        assert_eq!(AuthProviderType::from_str("api_key"), AuthProviderType::ApiKey);
        assert_eq!(AuthProviderType::from_str("apikey"), AuthProviderType::ApiKey);
        assert_eq!(AuthProviderType::from_str("custom"), AuthProviderType::Custom("custom".to_string()));
    }

    #[test]
    fn test_auth_provider_type_serialization() {
        let jwt_type = AuthProviderType::Jwt;
        let serialized = serde_json::to_string(&jwt_type).unwrap();
        let deserialized: AuthProviderType = serde_json::from_str(&serialized).unwrap();
        assert_eq!(jwt_type, deserialized);
    }
}